Kubernetes Pod 多网卡、IP 固定Underlay 网络解决方案
01Unnderlay 网络 的 IP 需求
随着数据中心私有云的发展,应用希望能直接获取并使用宿主机网络中的 IP 地址,实现在 Underlay 网络下的东西向和南北向通信;同时基于对 IPAM(IP地址管理) 的特殊需求,迫切希望能解决如下的一些诉求:
Pod 多网卡支持
- 为使 Pod 能通达不同的 Underlay 子网,需给应用的不同网卡分配不同子网下的 IP 地址,社区现有的方案配合 Multus 能分配多网卡 IP 地址,但是不能实现多网卡都固定 IP 地址。
- 社区现有的多网卡分配 IP 地址方案,还存在多网卡路由协调问题,例如:Pod 的默认路由在网卡 1 上,外部 Client 访问 Pod 网卡 2 的 IP 地址,当外部的源 IP 与 Pod 的网卡 2 不是同网段时,Pod 就会通过默认路由从而走到网卡 1 进行回包,请求向和回复向的转发路径不一致,因此外部的 Client 收不到回包,导致网络不可达。
有状态和无状态应用 IP 固定
- Pod 的 IP 地址常常受防火墙策略管控,防火墙只会允许特定的 IP 或者 IP 范围内的目标访问,因此 Pod IP 不相对固定,会对防火墙策略的修改产生极大的负担。
- 有状态应用的特殊性,不仅要求 Pod 的 IP 范围固定,更要求在 Pod 的生命周期内对 IP 地址的唯一绑定,可以保证应用的可用性、稳定性和可靠性。
- 传统微服务应用直接使用 Pod IP 进行微服务注册,对固定 IP 地址的需求。传统应用在云化改造前,是部署在裸金属环境上的,服务之间的网络未引入 NAT 地址转换,微服务架构中需要感知对方的源 IP 或目的 IP。
应用固定 IP 地址数量的弹性扩缩容
- 应用固定 IP 场景下,IP 地址数量的扩缩容问题。随着应用扩缩容,如果能够实现固定 IP 地址一起扩缩,将避免每次都需要去人工修改 IP 固定池。
- 应用固定 IP 场景下,IP 地址数量的冗余问题。应用在滚动更新时,新 Pod 副本先启动,才会删除旧 Pod,在此过程中,如果没有冗余的固定 IP 地址,那么新 Pod 副本会因为缺少新的固定 IP 而启动失败。
开源社区涌现出了一些开源项目,能够提供对接 Underlay 网络的 CNI 方案,但是仍然无法完全满足上述需求:
Kube-ovn v1.11 能够对接 underlay 网络,为实现固定 IP,必须在 annotation 上 hard code IP 地址,存在以下几个问题:
无法实现 固定 IP 的 CRD 化管理,因此查询 所有的 Pod 不方便,有可能因为运维失误导致出现 IP 冲突。
应用扩缩容时,需要人为添加或删除 annotation 中的 IP 地址。
因为应用的 IP 范围被固定了,可能在应用滚动发布时,新建的 Pod 可能会面临没有临时的固定 IP 可用。
Antrea v1.11 能对接 Underlay 网络,不支持 Deployment/Statefulset 类型副本数大于 1 的 IP 地址固定。可参考 Antrea 文档 [1]。
Calico 能够通过无隧道模式,配合 BGP 路由发布,实现对接 underlay 网络,但不支持 Deployment/Statefulset 类型的 IP 地址固定。
随着开源社区的不断发展,一个开源项目 SpiderPool 的出现,提供了一种全新的解决方案,能够满足上述应用在 Underlay 网络下的需求,下面一起来了解一下。
02 SpiderPool 的 Underlay 解决方案
SpiderPool是一个 Kubernetes 的 IPAM 插件项目,其主要针对于 Underlay 网络的 IP 地址管理需求而设计,能够为任何兼容第三方 IPAM 插件的 CNI 项目所使用。它克服了 Underlay 网络分配 IP 地址的复杂性,使得 IP 分配的运维工作像一些 Overlay 网络模型一样简单**,同时,它拥有应用 IP 地址固定、IP 地址自动弹性扩缩容、 多网卡、双栈支持等特点。更多说明参考 SpiderPool 介绍 [2]。
经过笔者测试,SpiderPool 最大的体验就是:Underlay 网络下 IP 地址的管理能力非常强大, 分配固定 IP 从未如此简单!
SpiderPool 可搭配 Multus [3]、Macvlan [4]、Calico [5]、SRI-OV [6]、ipvlan [7]、vlan [8]、ovs [9] 、Weave [10] 等多种 CNI 来完成完整的 Underlay 网络解决方案,并且 Spiderpool 还提供一个 Veth [11] 插件它能够帮助一些 CNI (例如 Macvlan、SR-IOV 等)解决如下问题:
- 帮助 main CNI 实现 Pod 和宿主机之间的通信,以解决 Pod 访问 clusterIP、Pod 的宿主机健康检查等问题。
- 在 Pod 多网卡场景下,能自动够协调多网卡间的策略路由,解决多网卡通信问题。
本文将以 Multus、Macvlan、Veth、SpiderPool 这套 Underlay 组合方案为例,通过如下网络拓扑图所示,展示讲解 Pod 多网卡的网络情况。
## 03 安装
根据 Spiderpool 的官方文档 搭建了一套 Multus 、Macvlan、Veth 、Spiderpool 的环境,以下是笔者根据自身环境已创建的 SpiderSubnet 实例:
1 | ~# kubectl get spidersubnet |
笔者的主机上有两张物理网卡,创建两个 Macvlan 的 Multus NetworkAttachmentDefinition 配置,分别用接入 10.6 与 10.7 的 Underlay 子网,以下是已创建的 Multus 的 NetworkAttachmentDefinition 配置
1 | ~# kubectl get network-attachment-definitions.k8s.cni.cncf.io -n kube-system |
## 04 固定多网卡 IP
以下的示例 Yaml 中, 会创建 2 个副本的 Deployment,其中:
- ipam.spidernet.io/subnets:用于指定 Spiderpool 的子网,Spiderpool 会自动在该子网中随机选择一些 IP 来创建固定 IP 池,与本应用绑定,实现 IP 固定的效果。因为使用了multus 创建了两张网卡,该 annotation 会为 Pod 创建 2 个属于不同 Underlay 子网的固定 IP 池。
- ipam.spidernet.io/ippool-ip-number:用于指定创建 IP 池 中 的 IP 数量。该 annotation 的写法支持两种方式:一种是数字的方式指定 IP 池的固定数量,例如 ipam.spidernet.io/ippool-ip-number:1;另一种方式是使用加号和数字指定 IP 池的相对数量,例如ipam.spidernet.io/ippool-ip-number:+1,即表示 IP 池中的数量会自动实时保持在应用的副本数的基础上多 1 个 IP,以解决应用在弹性扩缩容的时有临时的 IP 可用。
- v1.multus-cni.io/default-network:为应用创建一张默认网卡。
- K8s.v1.cni.cncf.io/networks: 为应用创建另一张网卡。
1 | cat <<EOF | kubectl create -f - |
最终,在 Deployment 创建时,SpiderPool 会随机从指定子网中选择一些 IP 来创建出两个固定 IP 池 与 Deployment Pod 的两张网卡分别形成绑定。
1 | ~# kubectl get spiderippool |
如下命令展示了 Pod 中的多网卡路由信息,Veth 插件能自动够协调多网卡间的策略路由,解决多网卡间的通信问题。
1 | ~# kubectl exec -ti test-app-6f4594ff67-fkqbw -- ip rule show |
经过多次测试,不断重启 Pod,其 Pod IP 都被固定在两个 IP 池范围内:
1 | ~# kubectl delete po -l app=test-app |
## 05 固定 IP 数量的 弹性扩缩容
创建 Deployment 时指定了注解 ipam.spidernet.io/ippool-ip-number: ‘+1’,其表示应用分配到的固定 IP 数量比应用的副本数多 1 个,在应用滚动更新时,能够避免旧 Pod 未删除,新 Pod 没有可用 IP 的问题。
以下演示了扩容场景,将应用的副本数从 2 扩容到 3,应用对应的两个固定 IP 池会自动从 3 个 IP 扩容到 4 个 IP,一直保持一个冗余 IP,符合预期:
1 | ~# kubectl scale deploy test-app --replicas 3 |
通过上述操作,SpiderPool 对于应用扩缩容的场景,只需要修改应用的副本数即可。
06 SpiderPool 的 更多功能
- 手动建池固定 IP
在需要防火墙等手段来精细管控网络安全场景下,网络管理员希望自己来直接指定应用的固定 IP 地址,而不是由 SpiderPool 自动从子网中随机选择 IP 。对此 SpiderPool 提供注解 ipam.spidernet.io/ippool 与 ipam.spidernet.io/ippools 能手动为应用绑定指定的 IP 池,但手动指定池将不支持自动扩缩容。参考手动建池 [12]。
- 预留 IP
设置全局的 IP 预留,使得集群不会分配出这些 IP 地址,这样能避免与集群外部的已用 IP 冲突,参考预留 IP [13]。
- 备用 IP 池
应用可设置多个 IP 池,实现 IP 资源的备用效果。可参考备用 IP 池 [14]。
- IP 回收
合理的 IP 回收机制设计,可最大保证 IP 资源的可用性。参考IP 回收机制 [15]。
- 分配和释放 IP 地址的高效性能
确保应用的快速发布和删除,且保证了集群在容灾场景下的快速恢复。查看性能数据 [16]。
07 总结
经过测试:Pod 能够通过 Pod IP、clusterIP、nodePort 等方式通信,在 Underlay 网络下,SpiderPool 搭配 Multus 、Macvlan、Veth 能支持多网卡固定 IP 地址的需求,这为解决多网卡固定 IP 地址提供了一种全新的方案。
资料索引
[1] Antrea 文档
[2] SpiderPool 功能介绍
[3] Multus
[4] Macvlan
[5] Calico
[6] SRI-OV
[7] ipvlan
[8] vlan
[9] ovs
[10] Weave
[11] Veth
[12] 手动建池
[13] 预留 IP
[14] 备用 IP 池
[15] IP 回收机制
[16] 性能数据